home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 January: Mac OS SDK / Dev.CD Jan 99 SDK1.toast / Development Kits / AIAT / Examples / Sources / PPAsyncHFSStore / PPAsyncHFSStoreStream.cp next >
Encoding:
Text File  |  1998-04-16  |  4.2 KB  |  145 lines  |  [TEXT/CWIE]

  1. // PPAsyncHFSStoreStream.cp
  2. // Implements IAStoreStream for asynchronous access to an Macintosh HFS file.
  3. //    Copyright:    © 1996 - 1998 by Apple Computer, Inc., all rights reserved.
  4.  
  5.  
  6.  
  7. #include "PPAsyncHFSStoreStream.h"
  8. #include <string.h>
  9. #include <Errors.h>
  10. #include <Files.h>
  11.  
  12. #include <LThread.h>
  13.  
  14. #include "IAStorage.h"
  15.  
  16.  
  17. IAStorage* MakePPAsyncHFSStorage(short vRef, long dirId, const StringPtr name, OSType c, OSType t) {
  18.     return IAMakeStorage(new PPAsyncHFSStoreStream(vRef, dirId, name, c, t));
  19. }
  20.  
  21.  
  22.  
  23.  
  24. PPAsyncHFSStoreStream::PPAsyncHFSStoreStream(short v, long d, const StringPtr n, OSType c, OSType t)
  25.     : HFSStoreStream(v,d,n,c,t) 
  26. {
  27. }
  28.  
  29.  
  30.  
  31. PPAsyncHFSStoreStream::PPAsyncHFSStoreStream(short v, long d, const StringPtr n, OSType c, OSType t, bool o, bool w, short f)
  32.     : HFSStoreStream(v,d,n,c,t,o,w,f) {
  33. }
  34.  
  35.  
  36.  
  37.  
  38. IAStoreStream* PPAsyncHFSStoreStream::Clone() {
  39.     return new PPAsyncHFSStoreStream(vRefNum, dirID, fileName, creator, fileType, isOpen, isWritable, fRefNum);
  40. }
  41.  
  42.  
  43.  
  44.  
  45.  
  46. void PPAsyncHFSStoreStream::Write(uint32 address, const byte* data, uint32 length) {
  47.     OSErr err;
  48.     SThreadParamBlk    asyncPBlock;
  49.     EventRecord theEvent;
  50.     LThread *thrd;
  51.  
  52.     IAThrowIfNot(isOpen, StoreError);
  53.  
  54.     asyncPBlock.ioPB.F.ioParam.ioRefNum = fRefNum;
  55.     asyncPBlock.ioPB.F.ioParam.ioBuffer = (Ptr)data;
  56.     asyncPBlock.ioPB.F.ioParam.ioReqCount = length;
  57.     asyncPBlock.ioPB.F.ioParam.ioPosMode = fsFromStart;
  58.     asyncPBlock.ioPB.F.ioParam.ioPosOffset = address;
  59.  
  60.     // If we're currently inside a thread, then call async and suspend it
  61.     if ((thrd = LThread::GetCurrentThread()) != nil && !LThread::InMainThread()) {
  62.         // Only Yield if there are other threads ready to do something
  63.         if (LThread::CountReadyThreads() > 1) {
  64.             thrd->SetupAsynchronousResume(&asyncPBlock);
  65.             err = ::PBWriteAsync(&asyncPBlock.ioPB.F);
  66.             // Note that this call doesn't necessarily yield any time depending on
  67.             // whether the write was immediately cached.
  68.             err = thrd->SuspendUntilAsyncResume(&asyncPBlock);
  69.             }
  70.         else {
  71.             asyncPBlock.ioPB.F.ioParam.ioCompletion = nil;
  72.             err = ::PBWriteSync(&asyncPBlock.ioPB.F);
  73.             }
  74.         // In any case, if user events are pending, then give the main thread a chance
  75.         // to process user I/O.  For some reason, EventAvail doesn't detect mouseDown
  76.         // events for us.
  77.         if (::EventAvail(everyEvent, &theEvent) || ::Button())
  78.             thrd->Yield();
  79.     }
  80.     else {
  81.         asyncPBlock.ioPB.F.ioParam.ioCompletion = nil;
  82.         err = ::PBWriteSync(&asyncPBlock.ioPB.F);
  83.     }
  84.  
  85.     IAThrowIf(err, StoreError);
  86.     IAAssert(asyncPBlock.ioPB.F.ioParam.ioActCount = length);
  87. }
  88.  
  89.  
  90.  
  91.  
  92. uint32
  93. PPAsyncHFSStoreStream::Read(uint32 address, byte* data,  uint32 length) {
  94.     OSErr err;
  95.     SThreadParamBlk    asyncPBlock;
  96.     EventRecord theEvent;
  97.     LThread *thrd;
  98.  
  99.     IAThrowIfNot(isOpen, StoreError);
  100.  
  101.     asyncPBlock.ioPB.F.ioParam.ioRefNum = fRefNum;
  102.     asyncPBlock.ioPB.F.ioParam.ioBuffer = (Ptr)data;
  103.     asyncPBlock.ioPB.F.ioParam.ioReqCount = length;
  104.     asyncPBlock.ioPB.F.ioParam.ioPosMode = fsFromStart;
  105.     asyncPBlock.ioPB.F.ioParam.ioPosOffset = address;
  106.  
  107.     // If we're currently inside a thread, then call async and suspend it
  108.     if ((thrd = LThread::GetCurrentThread()) != nil && !LThread::InMainThread()) {
  109.         // Only Yield if there are other threads ready to do something
  110.         if (LThread::CountReadyThreads() > 1) {
  111.             thrd->SetupAsynchronousResume(&asyncPBlock);
  112.             err = ::PBReadAsync(&asyncPBlock.ioPB.F);
  113.             // Note that this call doesn't necessarily yield any time depending on
  114.             // whether the read was from the disk cache.
  115.             err = thrd->SuspendUntilAsyncResume(&asyncPBlock);
  116.         }
  117.         else {
  118.             asyncPBlock.ioPB.F.ioParam.ioCompletion = nil;
  119.             err = ::PBReadSync(&asyncPBlock.ioPB.F);
  120.         }
  121.         // In any case, if user events are pending, then give the main thread a chance
  122.         // to process user I/O.  For some reason, EventAvail doesn't detect mouseDown
  123.         // events for us.
  124.         if (::EventAvail(everyEvent, &theEvent) || ::Button())
  125.             thrd->Yield();
  126.     }
  127.     else {
  128.         asyncPBlock.ioPB.F.ioParam.ioCompletion = nil;
  129.         err = ::PBReadSync(&asyncPBlock.ioPB.F);
  130.     }
  131.  
  132.     IAThrowIf(err && err != eofErr, StoreError);
  133.     return asyncPBlock.ioPB.F.ioParam.ioActCount;
  134. }
  135.  
  136.  
  137. // This handy method is missing from HFSStoreStream
  138. void PPAsyncHFSStoreStream::GetFSSpec(FSSpec *fileSpec)
  139. {
  140.     fileSpec->parID = dirID;
  141.     fileSpec->vRefNum = vRefNum;
  142.     BlockMoveData(fileName, fileSpec->name, fileName[0] + 1);
  143. }
  144.  
  145.